package com.qding.park.manager.service.core.biz;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import org.apache.commons.lang3.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import com.qding.park.common.core.exceptions.BaseException;
import com.qding.park.common.core.exceptions.ExceptionMessage;
import com.qding.park.common.core.exceptions.business.adapter.AdapterException;
import com.qding.park.common.core.exceptions.business.manager.adapterfactory.AdapterProxyCreateFail;
import com.qding.park.common.core.exceptions.business.manager.service.ServiceCoreException;
import com.qding.park.common.utils.OrderNumUtil;
import com.qding.park.manager.adapter.factory.AdapterParkProxyFactory;
import com.qding.park.manager.cache.ConfigDataCacheInter;
import com.qding.park.manager.pojo.TbInvitecard;
import com.qding.park.manager.pojo.TbParkspace;
import com.qding.park.manager.pojo.TbUserInfo;
import com.qding.park.manager.pojo.ap.ApVisitingReminder;
import com.qding.park.manager.pojo.enums.InviteStatusEnum;
import com.qding.park.manager.pojo.enums.OrderServiceType;
import com.qding.park.manager.pojo.sms.device.InviteVisitNotice;
import com.qding.park.manager.service.core.atomic.distributed.InviteDBAtomic;
import com.qding.park.manager.service.core.local.cache.DicCache;
import com.qding.park.manager.service.core.mapper.TbInvitecardMapper;
import com.qding.park.manager.service.core.mapper.TbParkspaceMapper;
import com.qding.park.manager.service.core.mapper.TbUserInfoMapper;
import com.qding.park.manager.sms.DevicePushInterfaceService;
import com.qding.park.target.common.adapter.InviteAdapter;
import com.qding.park.target.common.entity.AdInviteOrder;

/**
 * @ClassName InviteBiz
 * @Description TODO(邀请)
 * @author Administrator
 * @Date 2016年8月26日 下午2:09:22
 * @version 1.0.0
 */
@Component("inviteBiz")
public class InviteBiz {

	private static final Log _log = LogFactory.getLog(InviteBiz.class);
	@Autowired
	private TbUserInfoMapper tbUserInfoMapper;

	@Autowired
	private TbInvitecardMapper tbInvitecardMapper;

	@Autowired
	private TbParkspaceMapper tbParkspaceMapper;
	

	@Autowired
	private AdapterParkProxyFactory adapterParkProxyFactory;
	@Autowired
	private ConfigDataCacheInter configDataCacheInter;
	@Autowired
	private DevicePushInterfaceService devicePushInterfaceService;
	@Autowired
	private CarBiz  carBiz;
	@Autowired
	private  InviteDBAtomic  inviteDBAtomic;
	@Autowired
	private  DicCache  dicCache;

	@Transactional(rollbackFor = Throwable.class)
	public String createInvite(TbInvitecard tbInvitecard)
			throws AdapterProxyCreateFail, AdapterException, ServiceCoreException {
		
//		TbUserInfo tbUserInfo =carBiz.getUserAPP(tbInvitecard.getBjuserid());
		String userIdstr=configDataCacheInter.bjuserId2userId(tbInvitecard.getBjuserid());
		if(StringUtils.isBlank(userIdstr)){
			throw new ServiceCoreException(ServiceCoreException.TypeEnum.EXCEPTION_EXIST_INVITATION.getId(), null,
					ExceptionMessage.createExceptionMessage(
							ServiceCoreException.TypeEnum.EXCEPTION_EXIST_INVITATION.getDesc(),
							"没有此用户信息", "bjuserid" + tbInvitecard.getBjuserid()));
		}
		int userId=Integer.valueOf(userIdstr);
		tbInvitecard.setUserID(userId);
		
		int parkId = tbInvitecard.getParkID();
//		int userId = tbUserInfo.getId();
		String carNum = tbInvitecard.getCarNum();
		int num = tbInvitecardMapper.hasInvited(tbInvitecard);
		if (num > 0) {
			throw new ServiceCoreException(ServiceCoreException.TypeEnum.EXCEPTION_EXIST_INVITATION.getId(), null,
					ExceptionMessage.createExceptionMessage(
							ServiceCoreException.TypeEnum.EXCEPTION_EXIST_INVITATION.getDesc(),
							"该车辆在约定时间内已被您邀请过，请勿重复邀请", "parkId" + parkId + ",userId" + userId + ",carNum=" + carNum));
		}

		// 设置状态为 未来访
		tbInvitecard.setStatus(InviteStatusEnum.NOT_VISIT.getStatus());
		tbInvitecard.setId(OrderNumUtil.getOrderNum(userId, OrderServiceType.INVITE.getTag()));
		TbParkspace tbParkspace = configDataCacheInter.queryParkSpace(parkId);
		String parkCode = tbParkspace.getParkCode();
//		tbInvitecardMapper.save(tbInvitecard);
		int count=inviteDBAtomic.saveInvite(tbInvitecard);
		if(count==0){
			throw new ServiceCoreException(ServiceCoreException.TypeEnum.EXCEPTION_EXIST_INVITATION.getId(), null,
					ExceptionMessage.createExceptionMessage(
							ServiceCoreException.TypeEnum.EXCEPTION_EXIST_INVITATION.getDesc(),
							"该车辆在约定时间内已被您邀请过，请勿重复邀请", "parkId" + parkId + ",userId" + userId + ",carNum=" + carNum));
		}
		String orderId = tbInvitecard.getId();

		/******** 线下下发邀请单 **************/
		int supplierId = tbParkspace.getSupplierId();
		InviteAdapter  inviteAdapter=adapterParkProxyFactory.getInviteAdapter(String.valueOf(supplierId));
		AdInviteOrder apInviteOrder = new AdInviteOrder();
		apInviteOrder.setOrderId(String.valueOf(orderId));
		apInviteOrder.setCarNum(tbInvitecard.getCarNum());
		apInviteOrder.setParkCode(parkCode);
		apInviteOrder.setStartTime(tbInvitecard.getStartTime());
		apInviteOrder.setEndTime(tbInvitecard.getEndTime());
		inviteAdapter.createInvite(apInviteOrder);
		/******** 线下下发邀请单 **************/

		return orderId;
	}

	/**
	 * @Description (取消邀请)
	 * @param orderId
	 * @throws ServiceCoreException
	 * @throws AdapterProxyCreateFail
	 * @throws AdapterException
	 */
	@Transactional(rollbackFor = Throwable.class)
	public void cancelInvite(String orderId) throws ServiceCoreException, AdapterProxyCreateFail, AdapterException {
		TbInvitecard tbInvitecard = tbInvitecardMapper.queryById(orderId);
		if (null == tbInvitecard) {
			throw new ServiceCoreException(ServiceCoreException.TypeEnum.EXCEPTION_NOTFIND_INVITATION.getId(), null,
					ExceptionMessage.createExceptionMessage(
							ServiceCoreException.TypeEnum.EXCEPTION_NOFIND_USER.getDesc(), "没有此记录",
							"没有此邀请orderId=" + orderId));
		}

		int parkId = tbInvitecard.getParkID();
		int status = tbInvitecard.getStatus();

		if (status == InviteStatusEnum.VISITED.getStatus()) {
			// 已来访
//			throw new ServiceCoreException(ServiceCoreException.TypeEnum.EXCEPTION_INVITATION_CANCEL.getId(), null,
//					ExceptionMessage.createExceptionMessage(
//							ServiceCoreException.TypeEnum.EXCEPTION_INVITATION_CANCEL.getDesc(), "此邀请已来访",
//							"已来访的邀请orderId=" + orderId));
		} else if (status == InviteStatusEnum.CANCEL_VISITED.getStatus()) {
			// 已取消
			throw new ServiceCoreException(ServiceCoreException.TypeEnum.EXCEPTION_INVITATION_CANCEL.getId(), null,
					ExceptionMessage.createExceptionMessage(
							ServiceCoreException.TypeEnum.EXCEPTION_INVITATION_CANCEL.getDesc(), "此邀请已取消",
							"已取消的邀请orderId=" + orderId));
		} else if (status == InviteStatusEnum.EXPIRED_VISITED.getStatus()) {
			// 已过期
			throw new ServiceCoreException(ServiceCoreException.TypeEnum.EXCEPTION_INVITATION_CANCEL.getId(), null,
					ExceptionMessage.createExceptionMessage(
							ServiceCoreException.TypeEnum.EXCEPTION_INVITATION_CANCEL.getDesc(), "此邀请已过期",
							"已过期的邀请orderId=" + orderId));
		}
		TbParkspace tbParkspace = tbParkspaceMapper.queryParkInfoByParkId(parkId);
		String parkCode = tbParkspace.getParkCode();

		/******** 线下下发邀请单 **************/
		int supplierId = tbParkspace.getSupplierId();
		String carNum = tbInvitecard.getCarNum();
		InviteAdapter adapterProxy = adapterParkProxyFactory.getInviteAdapter(String.valueOf(supplierId));
		AdInviteOrder apInviteOrder = new AdInviteOrder();
		apInviteOrder.setOrderId(String.valueOf(orderId));
		apInviteOrder.setCarNum(tbInvitecard.getCarNum());
		apInviteOrder.setParkCode(parkCode);
		apInviteOrder.setStartTime(tbInvitecard.getStartTime());
		apInviteOrder.setEndTime(tbInvitecard.getEndTime());
		adapterProxy.cancelInvite(apInviteOrder);
		/******** 线下下发邀请单 **************/

		// 设置状态为已取消
		tbInvitecardMapper.cancelInvite(orderId, InviteStatusEnum.CANCEL_VISITED.getStatus());

	}

	/**
	 * @Title: queryInvitesByParkidCarnum @Description: TODO(根据parkId
	 * ,carNum查询有笑的邀请列表) @param @param parkId @param @param
	 * carNum @param @return 参数 @return List<TbInvitecard> 返回类型 @throws
	 */
	public List<TbInvitecard> queryInvitesByParkidCarnum(int supplyId, String parkCode, String carNum) {

		TbParkspace tbParkspace = tbParkspaceMapper.queryParkInfoByCodeSupplier(parkCode, supplyId);

		int parkId = tbParkspace.getId();

		return tbInvitecardMapper.queryInvitesByParkidCarnum(parkId, carNum);
	}

	@Transactional(rollbackFor = Throwable.class)
	public void inviteVisited(ApVisitingReminder apVisitingReminder) throws BaseException{
		// 供应商id
		String supplyId = apVisitingReminder.getSupplyID();
		// 车场方面的车辆编号
		String parkCode = apVisitingReminder.getParkId();
		// 卡号
		String cardCode = apVisitingReminder.getCardCode();
		// 车牌
		String carNum = apVisitingReminder.getCarNum();
		// 进场时间
		Date inDateTime = apVisitingReminder.getInDateTime();
		// 进场岗停
		String inRoom = apVisitingReminder.getInRoom();

		TbParkspace tbParkspace=configDataCacheInter.queryParkSpace(parkCode, Integer.valueOf(supplyId));
		int parkId=tbParkspace.getId();
		List<TbInvitecard>   tbInvitecards=tbInvitecardMapper.queryInvitesByParkidCarnum(parkId, carNum);
		
		// 计算被几个人邀请了
		List<Integer> listTemp = new ArrayList<Integer>();
		for (int i = 0; i < tbInvitecards.size(); i++) {
			int userId = tbInvitecards.get(i).getUserID();
			if (!listTemp.contains(userId)) {
				listTemp.add(userId);
			}
		}

		if (listTemp.size() > 1) {
			// 有多人邀请
			// 更新邀请单
			for (TbInvitecard tbInvitecard : tbInvitecards) {
				tbInvitecard.setStatus(InviteStatusEnum.VISITED.getStatus());
				tbInvitecard.setCheckInTime(inDateTime);
				int num=tbInvitecardMapper.inviteVisited(tbInvitecard);
//				if(num==0){
//					continue;
//				}
				/******** 线下下发取消邀请单 **************/
//				int supplierId = tbParkspace.getSupplierId();
//				AdapterProxy adapterProxy = adapterParkProxyFactory.createAdapterParkProxyBySupplierId(supplierId);
//				ApInviteOrder apInviteOrder = new ApInviteOrder();
//				apInviteOrder.setOrderId(String.valueOf(tbInvitecard.getId()));
//				apInviteOrder.setCarNum(tbInvitecard.getCarNum());
//				apInviteOrder.setParkId(parkCode);
//				apInviteOrder.setStartTime(tbInvitecard.getStartTime());
//				apInviteOrder.setEndTime(tbInvitecard.getEndTime());
//				adapterProxy.getInviteAdapter().cancelInvite(apInviteOrder);
				/******** 线下下发取消邀请单 **************/
			}
		} else {
			// 只有一人邀请
			// 向邀请发起者推送 消息提醒
			/******* 通过北京接口实现消息提醒推送 *******************/
			// 更新邀请单
			for (TbInvitecard tbInvitecard : tbInvitecards) {
				tbInvitecard.setStatus(InviteStatusEnum.VISITED.getStatus());
				tbInvitecard.setCheckInTime(inDateTime);
				int num=tbInvitecardMapper.inviteVisited(tbInvitecard);
				/*modity 修改　　每次邀请进场都要推送消息*/
//				if(num==0){
//					continue;
//				}
				
				/******** 线下下发取消邀请单 **************/
//				int supplierId = tbParkspace.getSupplierId();
//				AdapterProxy adapterProxy = adapterParkProxyFactory.createAdapterParkProxyBySupplierId(supplierId);
//				ApInviteOrder apInviteOrder = new ApInviteOrder();
//				apInviteOrder.setOrderId(String.valueOf(tbInvitecard.getId()));
//				apInviteOrder.setCarNum(tbInvitecard.getCarNum());
//				apInviteOrder.setParkId(parkCode);
//				apInviteOrder.setStartTime(tbInvitecard.getStartTime());
//				apInviteOrder.setEndTime(tbInvitecard.getEndTime());
//				adapterProxy.getInviteAdapter().cancelInvite(apInviteOrder);
				/******** 线下下发取消邀请单 **************/
				
				/******* 通过北京接口实现消息提醒推送 *******************/
				InviteVisitNotice notice = new InviteVisitNotice();
				TbUserInfo userInfo=tbUserInfoMapper.queryUserById(tbInvitecard.getUserID());
				notice.setCarNum(carNum);
				notice.setMemberId(userInfo.getBjCode());
				devicePushInterfaceService.inviteVisitNotice(notice);
			}
		}

	}

	/**
	 * @throws AdapterException @throws AdapterProxyCreateFail
	 * inviteTimeOut(邀请单超时) TODO(这里描述这个方法适用条件 – 可选) TODO(这里描述这个方法的执行流程 – 可选)
	 * TODO(这里描述这个方法的使用方法 – 可选) TODO(这里描述这个方法的注意事项 – 可选)
	 *
	 * @Title: inviteTimeOut @Description: TODO @param @param tbInvitecard
	 * 设定文件 @return void 返回类型 @throws
	 */
//	@Transactional(rollbackFor = Throwable.class)
//	public void inviteTimeOut(TbInvitecard invitecard) throws AdapterProxyCreateFail, AdapterException {
//
//		String id = invitecard.getId();
//		int num = tbInvitecardMapper.updateStatusTimeOut(id, InviteStatusEnum.EXPIRED_VISITED.getStatus());
//		if (num == 0) {
//			_log.info("id:" + id + " 邀请单数据不一致");
//
////			return;
//		}
//		TbInvitecard tbInvitecard = tbInvitecardMapper.queryById(id);
//
//		/******** 下发取消息邀请单操作 *****************/
////		TbParkspace tbParkspace = tbParkspaceMapper.queryParkInfoByParkId(tbInvitecard.getParkID());
//		TbParkspace tbParkspace =configDataCacheInter.queryParkSpace(tbInvitecard.getParkID());
//		String parkCode = tbParkspace.getParkCode();
//		int supplierId = tbParkspace.getSupplierId();
//		String carNum = tbInvitecard.getCarNum();
//		AdapterProxy adapterProxy = adapterParkProxyFactory.createAdapterParkProxyBySupplierId(supplierId);
//		AdInviteOrder apInviteOrder = new AdInviteOrder();
//		apInviteOrder.setOrderId(String.valueOf(id));
//		apInviteOrder.setCarNum(tbInvitecard.getCarNum());
//		apInviteOrder.setParkCode(parkCode);
//		apInviteOrder.setStartTime(tbInvitecard.getStartTime());
//		apInviteOrder.setEndTime(tbInvitecard.getEndTime());
//		adapterProxy.getInviteAdapter().cancelInvite(apInviteOrder);
//		/******** 下发取消息邀请单操作 ****************/
//
//	}
}
